package org.light.simpleauth.verb;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.light.core.Verb;
import org.light.core.Writeable;
import org.light.domain.Domain;
import org.light.domain.Dropdown;
import org.light.domain.Field;
import org.light.domain.JavascriptBlock;
import org.light.domain.JavascriptMethod;
import org.light.domain.Method;
import org.light.domain.Signature;
import org.light.domain.Statement;
import org.light.domain.Type;
import org.light.easyui.EasyUIPositions;
import org.light.exception.ValidateException;
import org.light.utils.StringUtil;
import org.light.utils.WriteableUtil;
import org.light.verb.FindById;

public class FindMyProfileUser extends Verb implements EasyUIPositions {

	@Override
	public Method generateDaoImplMethod() throws Exception {
		return null;
	}	

	@Override
	public Method generateDaoMethodDefinition() throws Exception {
		return null;
	}

	@Override
	public Method generateServiceMethodDefinition() throws Exception {
		return null;
	}

	@Override
	public Method generateServiceImplMethod() throws Exception  {
		return null;
	}
	
	public FindMyProfileUser(Domain domain,Set<Field> deniedFields) throws ValidateException{
		super();
		this.domain = domain;
		this.deniedFields = deniedFields;
		this.setVerbName("FindMyProfile"+StringUtil.capFirst(this.domain.getStandardName()));
		this.setLabel("获取用户资料");
		if  (domain.getLanguage().equalsIgnoreCase("english"))  this.setLabel("Find My Profile User");
	}

	@Override
	public Method generateControllerMethod() throws Exception {
		if (this.denied) return null;
		else {
			Method method = new Method();
			method.setStandardName(StringUtil.lowerFirst(this.getVerbName()));
			method.addSignature(new Signature(1,"headers","HeaderMap"));
			method.addSignature(new Signature(2,"session","ReadableSession"));
			method.setReturnType(new Type("String"));
	
			List<Writeable> sList = new ArrayList<Writeable>();
			sList.add(new Statement(1000L,1,"let stoken:std::option::Option<String> = session.get(\"token\");"));
			sList.add(new Statement(1100L,1,"let mut token:String = \"\".to_string();"));
			sList.add(new Statement(1200L,1,"match stoken {"));
			sList.add(new Statement(1300L,2,"Some(stoken) => {"));
			sList.add(new Statement(1400L,3,"token = stoken;"));
			sList.add(new Statement(1500L,2,"},"));
			sList.add(new Statement(1600L,2,"None => {"));
			sList.add(new Statement(1700L,3,"token =  headers.get(\"X-Token\").unwrap().to_str().unwrap().to_string();"));
			sList.add(new Statement(1800L,2,"}"));
			sList.add(new Statement(1900L,1,"}"));
			
			sList.add(new Statement(3000L,1,"let claims:Claims = jsonwebtoken::decode("));
			sList.add(new Statement(4000L,2,"&token,"));
			sList.add(new Statement(5000L,2,"&DecodingKey::from_secret(JWT_SECRET.as_bytes()),"));
			sList.add(new Statement(6000L,2,"&Validation::default(),"));
			sList.add(new Statement(7000L,1,")"));
			sList.add(new Statement(8000L,1,".map(|data| data.claims).unwrap();"));
			FindById find = new FindById(this.domain);
			sList.add(new Statement(10000L,1,"let "+this.domain.getSnakeDomainName()+" = service_"+StringUtil.getSnakeName(find.getVerbName())+"(claims.sub).await;"));
			sList.add(new Statement(11000L,2,"match "+this.domain.getSnakeDomainName()+" {"));
			sList.add(new Statement(12000L,2,"Err(_) => {"));
			sList.add(new Statement(14000L,3,"r#\"{  \"rows\": null,  \"success\": true}\"#.to_string()"));
			sList.add(new Statement(15000L,2,"},"));
			sList.add(new Statement(16000L,2,"Ok("+this.domain.getSnakeDomainName()+") => {"));
			sList.add(new Statement(17000L,3,"let json = serde_json::to_string_pretty(&"+this.domain.getSnakeDomainName()+").unwrap();"));
			sList.add(new Statement(19000L,0,""));
			sList.add(new Statement(20000L,3,"let mut map = Map::new();"));
			sList.add(new Statement(21000L,3,"map.insert(\"success\".to_string(), Value::from(true));"));
			sList.add(new Statement(22000L,3,"map.insert("));
			sList.add(new Statement(23000L,4,"\"rows\".to_string(),"));
			sList.add(new Statement(24000L,4,"serde_json::from_str(&json).unwrap(),"));
			sList.add(new Statement(25000L,3,");"));
			sList.add(new Statement(26000L,2,""));
			sList.add(new Statement(27000L,3,"let resultjson = serde_json::to_string_pretty(&map).unwrap();"));
			sList.add(new Statement(29000L,3,"return resultjson;"));
			sList.add(new Statement(30000L,2,"}"));
			sList.add(new Statement(31000L,1,"}"));

			method.setMethodStatementList(WriteableUtil.merge(sList));		
			return method;
		}
	}	

	@Override
	public JavascriptBlock generateEasyUIJSButtonBlock() throws Exception {
		return null;
	}

	@Override
	public JavascriptMethod generateEasyUIJSActionMethod() throws Exception {
		if (this.denied) return null;
		else {
			Domain domain = this.domain;
			JavascriptMethod method = new JavascriptMethod();
			method.setSerial(200);
			method.setStandardName(StringUtil.lowerFirst(this.getVerbName()));
			
			List<Writeable> sList = new ArrayList<Writeable>();
			long serial = 1000L;
			sList.add(new Statement(serial+1000L,1,"$.ajax({"));
			sList.add(new Statement(serial+2000L,2,"type: \"post\","));
			sList.add(new Statement(serial+3000L,2,"url: \"../"+ this.domain.getControllerPackagePrefix()+"profile"+this.domain.getControllerNamingSuffix()+"/"+StringUtil.lowerFirst(this.getVerbName())+"\","));
			sList.add(new Statement(serial+4000L,2,"dataType: 'json',"));
			sList.add(new Statement(serial+5000L,2,"success: function(data, textStatus) {"));
			sList.add(new Statement(serial+6000L,3,"if (data.success) {"));
			sList.add(new Statement(serial+7000L,4,"var rows = data.rows;"));
			sList.add(new Statement(serial+8000L, 4,
					"$(\"#ff\").find(\"#" + this.domain.getDomainId().getLowerFirstFieldName()
							+ "\").val(rows[\"" + this.domain.getDomainId().getLowerFirstFieldName() + "\"]);"));
			serial += 9000L;
			for (Field f : domain.getFieldsWithoutIdAndActive()) {
				if (!this.deniedFields.contains(f)) {
					if (f.getFieldType().equalsIgnoreCase("image")) {
						sList.add(new Statement(serial, 4, "if (!isBlank(rows[\""+f.getLowerFirstFieldName()+"\"]))	{"));
						sList.add(new Statement(serial+10, 5, "$(\"#ff\").find(\"#"+f.getLowerFirstFieldName()+"\").prop(\"src\",\"data:image/png;base64,\"+rows[\""+f.getLowerFirstFieldName()+"\"]);"));
						sList.add(new Statement(serial+20, 4, "}else{"));
						sList.add(new Statement(serial+30, 5, "$(\"#ff\").find(\"#"+f.getLowerFirstFieldName()+"\").prop(\"src\",\"../images/blank.jpg\");"));
						sList.add(new Statement(serial+40, 4, "}"));
					} else if (f.getFieldType().equalsIgnoreCase("date")) {
						sList.add(new Statement(serial, 4, "$(\"#ff\").find(\"#" + f.getLowerFirstFieldName()
						+ "\").textbox(\"setValue\",rows[\"" + f.getLowerFirstFieldName() + "\"]);"));
					} else if (f.getFieldType().equalsIgnoreCase("datetime")) {
						sList.add(new Statement(serial, 4, "$(\"#ff\").find(\"#" + f.getLowerFirstFieldName()
						+ "\").textbox(\"setValue\",rows[\"" + f.getLowerFirstFieldName() + "\"]);"));
					} else if (f instanceof Dropdown) {
						sList.add(new Statement(serial, 4, "if (!isBlank(rows[\""+f.getLowerFirstFieldName()+"\"])&& parseInt(rows[\""+f.getLowerFirstFieldName()+"\"])>0) $(\"#ff\").find(\"#" + f.getLowerFirstFieldName()
								+ "\").combobox(\"setValue\",rows[\"" + f.getLowerFirstFieldName() + "\"]);"));
					} else {
						if (f.getFieldType().equalsIgnoreCase("bool")) {
							sList.add(new Statement(serial, 4,
									"var " + f.getLowerFirstFieldName() + "Checkboxs = $(\"#ff\").find(\"input[name='"
											+ f.getLowerFirstFieldName() + "']\");"));
							sList.add(new Statement(serial + 100, 4,
									"for (var i=0;i<" + f.getLowerFirstFieldName() + "Checkboxs.length;i++){"));
							sList.add(new Statement(serial + 200, 5,
									"if (" + f.getLowerFirstFieldName() + "Checkboxs.get(i).value == \"\"+rows[\""
											+ f.getLowerFirstFieldName() + "\"]) " + f.getLowerFirstFieldName()
											+ "Checkboxs.get(i).checked=true;"));
							sList.add(new Statement(serial + 500, 4, "}"));
						} else if (f.isTextarea()) {
							sList.add(new Statement(serial, 4, "$(\"#ff\").find(\"#" + f.getLowerFirstFieldName()
									+ "\").val(rows[\"" + f.getLowerFirstFieldName() + "\"]);"));
						} else {
							sList.add(new Statement(serial, 4, "$(\"#ff\").find(\"#" + f.getLowerFirstFieldName()
									+ "\").textbox(\"setValue\",rows[\"" + f.getLowerFirstFieldName() + "\"]);"));
						}
					}
					serial += 1000;
				}
			}
			sList.add(new Statement(serial, 4, "var checkboxs = $(\"#ff\").find(\"input[name='"
					+ domain.getActive().getLowerFirstFieldName() + "']\");"));
			sList.add(new Statement(serial + 100, 4, "for (var i=0;i<checkboxs.length;i++){"));
			sList.add(new Statement(serial + 200, 5, "if (checkboxs.get(i).value == \"\"+rows[\""
					+ domain.getActive().getLowerFirstFieldName() + "\"]) checkboxs.get(i).checked=true;"));
			
			sList.add(new Statement(serial+40000L,4,"}"));
			sList.add(new Statement(serial+40000L,3,"}"));
			sList.add(new Statement(serial+41000L,2,"},"));
			sList.add(new Statement(serial+42000L,2,"complete : function(XMLHttpRequest, textStatus) {"));
			sList.add(new Statement(serial+43000L,2,"},"));
			sList.add(new Statement(serial+44000L,2,"error : function(XMLHttpRequest,textStatus,errorThrown) {"));
			sList.add(new Statement(serial+45000L,3,"alert(\"Error:\"+textStatus);"));
			sList.add(new Statement(serial+46000L,3,"alert(errorThrown.toString());"));
			sList.add(new Statement(serial+47000L,2,"}"));
			sList.add(new Statement(serial+48000L,1,"});"));
			
			method.setMethodStatementList(WriteableUtil.merge(sList));
			return method;

		}
	}

	@Override
	public Method generateDummyDaoImplMethod() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

}
